package com.front.web.wx.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.redisUtils.JedisUtils;
import com.bootdo.common.utils.HttpUtil;
import com.bootdo.common.utils.Sha1Utils;
import com.bootdo.common.utils.SortUtils;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.lvyou.domain.XcxConfig;
import com.bootdo.wx.domain.Config;
import com.bootdo.wx.domain.WxUser;
import com.bootdo.wx.service.WxUserService;

public class WechatUtil {
	public static String CheckSignature(HttpServletRequest request,String token){
        
        String signature=request.getParameter("signature");
        String timestamp=request.getParameter("timestamp");
        String nonce=request.getParameter("nonce");
        //第一步中填写的token一致
        ArrayList<String> list=new ArrayList<String>();
        list.add(nonce);
        list.add(timestamp);
        list.add(token);

        //字典序排序
        Collections.sort(list);
        //SHA1加密
        String checksignature=Sha1Utils.getSha1(list.get(0)+list.get(1)+list.get(2));
        System.out.println(signature);
        System.out.println(checksignature);

        if(checksignature.equals(signature)){
            return request.getParameter("echostr");
        }
        return null;    
    }
	
	
	//Sha1签名
	/*public static String getSha1(String str) {
		if (str == null || str.length() == 0) {
			return null;
		}
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
		'a', 'b', 'c', 'd', 'e', 'f' };
	
	
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));
			byte[] md = mdTemp.digest();
			int j = md.length;
			char buf[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
			byte byte0 = md[i];
			buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
			buf[k++] = hexDigits[byte0 & 0xf];
		}
			return new String(buf);
		} catch (Exception e) {
			return null;
		}
	}*/

	
	
	
	
	/**
	 * 
	 * @param request
	 * @param config
	 * @param redirectUri  参考 /f/getWxCode
	 * @throws UnsupportedEncodingException
	 */
	public static String getCode(HttpServletRequest request,Config config,String redirectUri) throws UnsupportedEncodingException {
		String path = request.getContextPath();
		String basePath = request.getScheme() + "://" + request.getServerName() + path;
		String getOpenIdUrl 
		="https://open.weixin.qq.com/connect/oauth2/authorize"
				+ "?appid="+config.getWxAppId()+"&redirect_uri="+URLEncoder.encode(basePath+"/f/getWxCode?userId="+config.getUserId())+"&response_type=code&scope=snsapi_userinfo"
				+ "&state="+redirectUri+"#wechat_redirect";
		System.out.println(getOpenIdUrl);
		return getOpenIdUrl;
	}
	

	/**
	 * 	得到获取用户信息的token
	 * @param code
	 * @param config
	 * @return
	 */
	public static String getOpenId(String code,Config config,WxUserService userService) {
		
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
				+ "appid="+config.getWxAppId()+"&secret="+config.getWxAppSecret()+"&code="+code
				+"&grant_type=authorization_code";
		
		String asstoken = null;
		String openId = null;
		 try {
			String r = HttpUtil.doGet(url);
			asstoken =  JSONObject.parseObject(r).getString("access_token");
			openId = JSONObject.parseObject(r).getString("openid");	
			String memberInfo = HttpUtil.doGet("https://api.weixin.qq.com/cgi-bin/user/info?access_token="+TokenUtils.getToken(config)+"&openid="+openId+"&lang=zh_CN");
			System.err.println("memberInfo = "+memberInfo);
			JSONObject  m = JSONObject.parseObject(memberInfo);
			Map map = new HashMap();
			map.put("openId", openId);
			
			WxUser wxUser  = null;
			List<WxUser> l =  userService.list(map);
			if(null != l && l.size() > 0) {
				wxUser = l.get(0);
			}
			if(null == wxUser) {
				wxUser = new WxUser();
				wxUser.setSex(m.getString("sex"));
				wxUser.setSubscribeTime(m.getInteger("subscribe"));
				wxUser.setNickname(m.getString("nickname"));
				wxUser.setOpenId(openId);
				wxUser.setCity(m.getString("city"));
				wxUser.setProvince(m.getString("province"));
				wxUser.setCountry(m.getString("country"));
				wxUser.setHeadimgurl(m.getString("headimgurl"));
				userService.save(wxUser);
			}else {
				wxUser.setSex(m.getString("sex"));
				wxUser.setNickname(m.getString("nickname"));
				wxUser.setCity(m.getString("city"));
				wxUser.setSubscribeTime(m.getInteger("subscribe"));
				wxUser.setProvince(m.getString("province"));
				wxUser.setCountry(m.getString("country"));
				wxUser.setOpenId(openId);
				wxUser.setHeadimgurl(m.getString("headimgurl"));
				userService.update(wxUser);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return openId;
	}
	
	
	
	
	/**
	 * 得到jstikit
	 * @param config
	 * @return
	 * @throws Exception
	 */
	private static String getJsApiTicket(Config config) throws Exception {
		String jstkit = JedisUtils.get("wx_jstikit_uer="+config.getUserId());		
		if(StringUtils.isEmpty(jstkit)) {
			String temp =  HttpUtil.doGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+TokenUtils.getToken(config)+"&type=jsapi");
			JSONObject j  = JSONObject.parseObject(temp);
			jstkit = j.getString("ticket");
			JedisUtils.set("wx_jstikit_uer="+config.getUserId(), jstkit, 7000);
		}
		return jstkit;
	}
	
	

	
	public static Map getJsApi(Config config,HttpServletRequest request) throws Exception {
		 String jsapi_ticket = getJsApiTicket(config);
		 String noncestr = UUID.randomUUID().toString().replaceAll("-", "");
         long timestamp = new Date().getTime()/1000;
         String url = request.getRequestURL() + "";
 		 if(request.getQueryString() != null){
 			url += "?" + request.getQueryString().substring(0, request.getQueryString().length());
 		 }       
         HashMap map = new HashMap();
		 map.put("noncestr", noncestr);
		 map.put("timestamp", timestamp+"");
		 map.put("jsapi_ticket", jsapi_ticket);
		 map.put("url",url);
		 String r =  SortUtils.FormatBizQueryParaMap(map, false, false, true);
		 String signature =  "";
		 try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(r.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		 } catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		 } catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		 }
	 	 Map ret = new HashMap();
		 ret.put("url", url);
		 ret.put("jsapi_ticket", jsapi_ticket);
		 ret.put("nonceStr", noncestr);
		 ret.put("timestamp", timestamp);
		 ret.put("signature", signature);
		 return ret;
	}

	public static Map getJsApi(Config config,String url) throws Exception {
		String jsapi_ticket = getJsApiTicket(config);
		String noncestr = UUID.randomUUID().toString().replaceAll("-", "");
		long timestamp = new Date().getTime()/1000;
		HashMap map = new HashMap();
		map.put("noncestr", noncestr);
		map.put("timestamp", timestamp+"");
		map.put("jsapi_ticket", jsapi_ticket);
		map.put("url",url);
		String r =  SortUtils.FormatBizQueryParaMap(map, false, false, true);
		String signature =  "";
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(r.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		Map ret = new HashMap();
		ret.put("url", url);
		ret.put("jsapi_ticket", jsapi_ticket);
		ret.put("nonceStr", noncestr);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);
		return ret;
	}
	
	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}



}
